// 封装一个响应式的函数
class Depend {
  constructor() {
    this.reactiveFns = []
  }
  appDepend(reactiveFn) {
    this.reactiveFns.push(reactiveFn)
  }
  notify() {
    this.reactiveFns.forEach(fn => {
      fn()
    })
  }
}

let activeReactiveFn = null

function watchFn(fn) {
  activeReactiveFn = fn
  fn()
  activeReactiveFn = null
}

// 封装一个获取depend函数
const targetMap = new WeakMap()

function getDepend(target, key) {
  // 根据target对象获取map的过程
  let map = targetMap.get(target)
  if (!map) {
    map = new Map()
    targetMap.set(target, map)
  }
  // 根据key获取真实的depend对象
  let depend = map.get(key)
  if (!depend) {
    depend = new Depend()
    map.set(key, depend)
  }
  return depend
}



// 对象的响应式
const obj = {
  name: 'why', // new Depend 对应一个depend对象
  age: 18 // new Depend 对应一个depend对象
}

// 监听对象的属性变化:Proxy(vue2)/Object.defineProperty(vue)
const objProxy = new Proxy(obj, {
  get(target, key, receiver) {
    // 根据target 和 key 获取对应的 depend
    const depend = getDepend(target, key)
    // 给depend对象中添加对应的响应函数
    depend.appDepend(activeReactiveFn)
    return Reflect.get(target, key, receiver)
  },
  set(target, key, newValue, receiver) {
    Reflect.set(target, key, newValue, receiver)
    // depend.notify()
    const depend = getDepend(target, key)
    depend.notify()
  }
})


watchFn(function () {
  console.log('---------------第一个name函数开始');
  console.log('你好啊,李银河');
  console.log('Hello World');
  console.log(objProxy.name);
  console.log('-------------第一个name函数结束');
})


watchFn(function () {
  console.log(objProxy.name, 'demo响应');
})

watchFn(function () {
  console.log(objProxy.age, 'age发生变化需要执行---------------------1');
})

watchFn(function () {
  console.log(objProxy.age, 'age发生变化需要执行---------------------2');
})


console.log('0000000000000000000000000000000000000000000000000000');

objProxy.age = 18